﻿using SMART_VIET_V01.Lib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SMART_VIET_V01
{
    public partial class frm_vedothi_ : Form
    {
        int max_x, max_y;
        Graphics g;
        ArrayList arr;
        int max, min, x1, y1, x2, y2, x0, y0, k = 30, delay = 0;
        int m_x, m_y;
        int begin_x, end_x;
        List<string> fxList = new List<string>();
        Dictionary<string, List<string>> modules = new Dictionary<string, List<string>>();

        Dictionary<string, Dictionary<string, dothiObject>> listModules = new Dictionary<string, Dictionary<string, dothiObject>>();
        Dictionary<string, dothiObject> dothi = new Dictionary<string, dothiObject>();
        Dictionary<string, dothiObject> tructoado = new Dictionary<string, dothiObject>();

        bool stop = false, repaint = false;

        public frm_vedothi_()
        {
            InitializeComponent();
            listModules.Add("1", null);
            listModules.Add("2", null);
            listModules.Add("3", null);
            listModules["1"] = tructoado;
            listModules["2"] = dothi;
            init();
        }

        void init()
        {
            g = PicPaint.CreateGraphics();
            delay = 0;
            k = 30;
            x0 = max_x / 2;
            y0 = max_y / 2;
            frmMain_Resize(null, null);
            trkZoom.Value = 5;
            stop = false;

            dothiObject ob = new dothiObject();
            ob.pen = new Pen(Color.Black, 2);
            ob.toado_x = x0;
            ob.toado_y = y0;
            ob.begin_x = begin_x;
            ob.end_x = end_x;
            ob.begin_y = 1;
            ob.end_y = max_y;
            ob.type = 1;
            ob.g = g;
            ob.k = k;
            ob.stop = stop;
            tructoado.Add("Trục tọa độ", ob);
            loadTree();
        }




        void loadTree()
        {
            treeModules.Nodes.Clear();
            foreach (var item in listModules)
            {
                TreeNode node = new TreeNode();
                node.Tag = item.Key;
                switch (item.Key)
                {
                    case "1":
                        node.Text = "Trục tọa độ";
                        node.Name = "Trục tọa độ";
                        break;
                    case "2":
                        node.Text = "Đồ thị";
                        node.Name = "Đồ thị";
                        break;
                    case "3":
                        node.Text = "Chú thích";
                        node.Name = "Chú thích";
                        break;
                    default:
                        break;
                }
                treeModules.Nodes.Add(node);
                if (item.Value != null)
                {
                    foreach (var draw in item.Value)
                    {
                        TreeNode child = new TreeNode();
                        child.Text = draw.Key;
                        child.Tag = draw.Key;
                        node.Nodes.Add(child);
                    }
                }
               
                node.Expand();
            }

        }
        private void btChen_Click(object sender, EventArgs e)
        {

            Math_Function fn = new Math_Function();
            string bieuthuc = txtBieuthuc.Text.ToLower();
            fn.Parse(bieuthuc);
            fn.Infix2Postfix();
            arr = fn.Variables;

            if (arr.Count != 1)
            {
                MessageBox.Show("Biểu thức không hợp lệ. Vui lòng nhập lại !\n\nVí dụ: (sin(x)+3)/(x+4)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else
            {
                if (arr[0].ToString() != "x")
                {
                    MessageBox.Show("Biểu thức không hợp lệ. Vui lòng nhập lại !\n\nVí dụ: (sin(x)+3)/(x+4)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            foreach (var item in listModules)
            {
                if (item.Key.Equals("2"))
                {
                    if (!item.Value.ContainsKey(bieuthuc.Replace(" ", "")))
                    {
                        dothiObject ob = new dothiObject();
                        ob.mausac = (cb_mausac.EditValue != null) ? (Color)cb_mausac.EditValue : Color.Blue;
                        ob.begin_x = x0;
                        ob.begin_y = y0;
                        ob.end_y = max_y;
                        ob.fn = fn;
                        ob.k = k;
                        ob.type = 2;
                        ob.arr = arr;
                        ob.stop = stop;
                        ob.delay = delay;
                        ob.g = g;
                        ob.thuchienVe();
                        dothi.Add(bieuthuc, ob);
                    }
                }
            }
            loadTree();
        }
        private void frmMain_Resize(object sender, EventArgs e)
        {
            max_x = PicPaint.Width;
            max_y = PicPaint.Height;
            k = 30;
            x0 = (int)(max_x / 2);
            y0 = (int)(max_y / 2);

            begin_x = (int)(PicPaint.Width / 2) - (PicPaint.Height / 2);
            end_x = begin_x + max_y;

            min = -begin_x / k - 1;
            max = begin_x / k + 1;


        }
        private void paintMultiGraph()
        {
            PicPaint.Refresh();
            g = PicPaint.CreateGraphics();
            btChen.Enabled = false;
            Application.DoEvents();
            int.TryParse(txtMin.EditValue.ToString(), out min);
            int.TryParse(txtMax.EditValue.ToString(), out max);
            ttStatus.Caption = "Trạng thái: Đang vẽ ....";
            Application.DoEvents();
            foreach (var moduleGr in listModules)
            {
                if (moduleGr.Value != null)
                {
                    foreach (var ob in moduleGr.Value)
                    {
                        switch (ob.Value.type)
                        {
                            case 1:
                                ob.Value.toado_x = x0;
                                ob.Value.toado_y = y0;
                                ob.Value.begin_x = begin_x;
                                ob.Value.end_x = end_x;
                                ob.Value.begin_y = 1;
                                ob.Value.end_y = max_y;
                                ob.Value.type = 1;
                                ob.Value.g = g;
                                ob.Value.k = k;
                                break;
                            case 2:
                                ob.Value.begin_x = x0;
                                ob.Value.begin_y = y0;
                                ob.Value.end_y = max_y;
                                ob.Value.k = k;
                                ob.Value.type = 2;
                                ob.Value.arr = arr;
                                ob.Value.stop = stop;
                                ob.Value.g = g;
                                ob.Value.delay = delay;
                                break;
                            default:
                                break;
                        }
                        ob.Value.thuchienVe();
                    }
                }

            }
            btChen.Enabled = true;
            delay = 0;
            ttStatus.Caption = "Trạng thái: Hoàn tất !";

        }
        private void AutoMinMax()
        {
            min = -x0 / k - 1;
            max = (max_x - x0) / k + 1;
            txtMin.EditValue = min.ToString();
            txtMax.EditValue = max.ToString();
        }

        private void frm_vedothi_Load(object sender, EventArgs e)
        {

        }

        private void btZoom_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            trkZoom.Visible = !trkZoom.Visible;
        }

        private void trkZoom_MouseUp(object sender, MouseEventArgs e)
        {
            k = (trkZoom.Value + 1) * 5;
            AutoMinMax();
            paintMultiGraph();
            trkZoom.Focus();
        }

        private void btZoomPlus_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            btZoomPlus.Enabled = false;
            k = k + 10;
            AutoMinMax();
            paintMultiGraph();
            btZoomPlus.Enabled = true;
        }

        private void btZoomMi_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (k <= 10) return;
            btZoomMi.Enabled = false;
            k = k - 10;
            AutoMinMax();
            paintMultiGraph();
            btZoomMi.Enabled = true;
        }

        private void PicPaint_MouseDown(object sender, MouseEventArgs e)
        {
            PicPaint.Cursor = Cursors.Hand;
            m_x = e.X;
            m_y = e.Y;
            ttStatus.Caption = "Giữ và kéo chuột để di chuyển tọa độ đồ thị !";
        }

        private void PicPaint_MouseUp(object sender, MouseEventArgs e)
        {
            PicPaint.Cursor = Cursors.Default;
            int x = e.X - m_x;
            int y = e.Y - m_y;

            if (Math.Abs(x) >= 20 || Math.Abs(y) >= 20)
            {
                x0 += x;
                y0 += y;

                AutoMinMax();

                paintMultiGraph();
            }
        }

        private void frm_vedothi_Paint(object sender, PaintEventArgs e)
        {
            frmMain_Resize(sender, e);
            AutoMinMax();
            paintMultiGraph();
        }

        private void frm_vedothi_SizeChanged(object sender, EventArgs e)
        {
            frmMain_Resize(sender, e);
            AutoMinMax();
            paintMultiGraph();
        }

        private void frm_vedothi_ResizeEnd(object sender, EventArgs e)
        {
            frmMain_Resize(sender, e);
            AutoMinMax();
            paintMultiGraph();
        }

    }
}
